package com.yanqu.road.dataHelper.action.excel;

import com.yanqu.road.dataHelper.gameServer.GameServer;
import com.yanqu.road.dataHelper.manager.ConfigMgr;
import com.yanqu.road.dataHelper.repair.BaseRepair;
import com.yanqu.road.entity.player.UserBuilding;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author xx
 * @Date 2020/11/11
 */
public class ReduceStaff extends BaseRepair {

    public ReduceStaff(GameServer gameServer) {
        super(gameServer);
    }

    @Override
    public void repair(long param1, String param2) {

    }

    public void go(long serverId, Map<String, Map<String, String>> map) {
        for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
            long userId = Long.parseLong(entry.getKey());
            if (userId == 111000040004758L) {
                continue;
            }
            BigInteger userEarnSpeed = getUserEarnSpeed(serverId, userId);
            if (userEarnSpeed == null) {
                System.out.println("serverId: " + serverId + "    userId:  " + userId + "  can't find speed");
                getLogger().error("userId {} cannot find ", userId);
                continue;
            }
            getLogger().error("userId {}, earnSpeed {}", userId, userEarnSpeed);
            long totalSec = 0;
            int mugongNum = 0;
            Map<String, String> itemMap = entry.getValue();
            for (Map.Entry<String, String> data : itemMap.entrySet()) {
                int itemId = Integer.parseInt(data.getKey());
                int value = Integer.parseInt(data.getValue());
                if (itemId == 110031) {
                    //分钟卡
                    totalSec = totalSec + 60 * value;
                } else if (itemId == 110032) {
                    //小时卡
                    totalSec = totalSec + 3600 * value;
                } else if (itemId == 110069) {
                    //木工卡
                    mugongNum = value;
                }
            }
            //先扣身上的木工
            int bagNum = getBagItem(userId, 110069);
            getLogger().error("needRemove mugong {}, bagNum {}", mugongNum, bagNum);
            if (bagNum >= mugongNum) {
                bagNum = bagNum - mugongNum;
                mugongNum = 0;
            } else {
                mugongNum = mugongNum - bagNum;
                bagNum = 0;
            }
            saveBagItem(userId, 110069, bagNum);
            Map<Integer, UserBuilding> buildingMap = getUserBuilding(userId);
            for (UserBuilding building : buildingMap.values()) {
                getLogger().info("user {} origin building {}, num {}", building.getUserId(), building.getBuildingId(), building.getStaffCount());
            }
            while (mugongNum > 0) {
                boolean isReduce = false;
                for (UserBuilding building : buildingMap.values()) {
                    int staffCount = building.getStaffCount();
                    if (staffCount > 0) {
                        isReduce = true;
                        building.setStaffCount(staffCount - 1);
                        mugongNum--;
                        if (mugongNum <= 0) {
                            break;
                        }
                    }
                }
                if (!isReduce || mugongNum <= 0) {
                    break;
                }
            }
            BigInteger needRemoveMoney = userEarnSpeed.multiply(BigInteger.valueOf(totalSec * 70 / 100));
            getLogger().info("userId {}, totalSec {}, needMoney {}", userId, totalSec, needRemoveMoney);
            BigInteger totalCost = BigInteger.ZERO;
            while (true) {
                boolean isReduce = false;
                for (UserBuilding building : buildingMap.values()) {
                    int staffCount = building.getStaffCount();
                    if (staffCount > 0) {
                        BigInteger staffCost = ConfigMgr.getStaffCost(building.getBuildingId(), staffCount);
                        totalCost = totalCost.add(staffCost);
                        building.setStaffCount(staffCount - 1);
                        isReduce = true;
                        if (totalCost.compareTo(needRemoveMoney) >= 0) {
                            break;
                        }
                    }
                }
                if (totalCost.compareTo(needRemoveMoney) >= 0 || !isReduce) {
                    break;
                }
            }
            for (UserBuilding building : buildingMap.values()) {
                saveBuilding(building);
            }
        }
    }

    private void saveBuilding(UserBuilding data) {
        //System.out.println("userId:  " + data.getUserId() + " , buildingId:  " + data.getBuildingId() + ",   staffNum: " + data.getStaffCount());
        getLogger().info("userId {}, buildingId {}, staffNum: {}", data.getUserId(), data.getBuildingId(), data.getStaffCount());
        PreparedStatement call = null;
        String sql = "UPDATE t_u_building SET staffCount=? where userId=? and buildingId=?";
        try {
            call = getGameServer().getConnection().prepareStatement(sql);
            int i = 1;
            call.setInt(i++, data.getStaffCount());
            call.setLong(i++, data.getUserId());
            call.setInt(i++, data.getBuildingId());
            boolean b = call.executeUpdate() > 0;
        } catch (Exception e) {
        } finally {
            getGameServer().closeConnection(call, null);
        }
    }

    private void saveBagItem(long userId, int goodsId, int num) {
        //System.out.println("userId:  " + userId + " , goodsId:  " + goodsId + ",   num: " + num);
        getLogger().info("userId {}, goodsId {}, num: {}", userId, goodsId, num);
        PreparedStatement call = null;
        String sql = "UPDATE t_u_bag SET num=? WHERE goodsId=? and userId=?";
        try {
            call = getGameServer().getConnection().prepareStatement(sql);
            int i = 1;
            call.setLong(i++, num);
            call.setInt(i++, goodsId);
            call.setLong(i++, userId);
            boolean b = call.executeUpdate() > 0;
        } catch (Exception e) {

        } finally {
            getGameServer().closeConnection(call, null);
        }
    }

    private BigInteger getUserEarnSpeed(long serverId, long userId) {
        int activityId = 0;
        if (serverId >= 11100001 && serverId <= 11100008) {
            activityId = 9008659;
        } else if (serverId >= 11100009 && serverId <= 11100016) {
            activityId = 9008660;
        } else if (serverId >= 11100017 && serverId <= 11100024) {
            activityId = 9008661;
        } else if (serverId >= 11100025 && serverId <= 11100034) {
            activityId = 9008684;
        }

        CallableStatement call = null;
        ResultSet rs = null;
        String sql = "select preValue from t_u_activity_condition where userId=? and activityId = ? and type = 14";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            call.setLong(1, userId);
            call.setLong(2, activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                return new BigInteger(rs.getString("preValue"));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
        return null;
    }


    public Map<Integer, UserBuilding> getUserBuilding(long userId) {
        Map<Integer, UserBuilding> dataMap = new HashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_u_building where userId = ? order by buildingId desc";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            int i = 1;
            call.setLong(i++, userId);
            rs = call.executeQuery();
            while (rs.next()) {
                UserBuilding data = new UserBuilding();
                data.setBuildingId(rs.getInt("buildingId"));
                data.setUserId(rs.getLong("userId"));
                data.setStaffCount(rs.getInt("staffCount"));
                data.setLastUpdateTime(rs.getLong("lastUpdateTime"));
                data.setLevel(rs.getInt("level"));
                List<Integer> idList = StringUtils.stringToIntegerListNoZero(rs.getString("patronsIdList"), ",");
                List<Integer> patronsIdList = new ArrayList<>();
                for (Integer id : idList) {
                    if (!patronsIdList.contains(id)) {
                        patronsIdList.add(id);
                    }
                }
                data.setPatronsIdList(patronsIdList);
                dataMap.put(data.getBuildingId(), data);
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
        return dataMap;
    }

    public int getBagItem(long userId, int itemId) {
        Map<Integer, UserBuilding> dataMap = new HashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select num from t_u_bag where userId=? and goodsId = ?";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            int i = 1;
            call.setLong(i++, userId);
            call.setInt(i++, itemId);
            rs = call.executeQuery();
            while (rs.next()) {
                return rs.getInt("num");
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
        return 0;
    }


}
